
package vectors;

import Exceptions.VectorIndexOutOfBoundsException;
import Exceptions.IncompatibleVectorSizesException;
import java.util.*;
import java.io.*;

public class JArrayList implements VectorIn,Serializable {
private ArrayList<Double> aList;    
private ArrayList observer;

public JArrayList(){
    aList = new ArrayList<Double >();
    observer = new ArrayList();
}
public JArrayList(int length){
    aList = new ArrayList<Double>(length);
    observer = new ArrayList();
}
public JArrayList(Double ... e) {
        for (Double elem : e) {
            aList.add(elem);
        observer = new ArrayList();
        }
    }
    @Override
    public void setElement(double value, int index) {
       // if (index < 0 || index >= getSize())
           // throw new VectorIndexOutOfBoundsException();
        
            aList.set(index, value);
        elementNotifyObservers(index);
    }
@Override
public void add(double element){
    aList.add(element);
     updateNotifyObservers();
}
    @Override
    public Double getElement(int index) {
        if (index < 0 || index > getSize())
            throw new VectorIndexOutOfBoundsException();
        return aList.get(index);
    }

    @Override
    public int getSize() {
        return aList.size();
    }

    @Override
    public void massiveToVector(double[] massive) {
       for(int i = 0; i < massive.length;i++){
        aList.add(massive[i]);
         updateNotifyObservers();
      }
}
    @Override
    public void objectToVector(VectorIn Vector1) {
        for(int i = 0; i < Vector1.getSize(); i++){
            aList.add(Vector1.getElement(i));
     updateNotifyObservers();
        }
}
    @Override
    public void multiplyVector(double multiply) {
        for (int i = 0; i < getSize();i++){
        aList.set(i,aList.get(i) * multiply);
    updateNotifyObservers();
        }   
    }

    @Override
    public void vectorPlusVector(VectorIn Vector1)throws IncompatibleVectorSizesException {
         if(aList.size() != Vector1.getSize()){
        throw new IncompatibleVectorSizesException();
    }else{
         for(int i = 0; i < aList.size(); i++){  
            aList.set(i,aList.get(i) + Vector1.getElement(i));
     updateNotifyObservers();
    }
  }
 }

    @Override
public boolean equalsVectors(VectorIn Vector1) {
        boolean f;
    if(aList.size() != Vector1.getSize() )
          return false;
      for (int i = 0; i < aList.size(); i++){
          if(aList.get(i)!= Vector1.getElement(i))
           return false;
}
          return true;
    }
@Override
public boolean equals(Object obj) {
        if (obj == null)
            return false;
        if(!(obj instanceof VectorIn))
            return false;
        VectorIn vec = (VectorIn) obj;
        if (this.aList.size() != vec.getSize())
            return false;

        for (int i = 0; i < this.aList.size(); i++) {
            if(getElement(i) != vec.getElement(i))
                return false;
        }

        return true;
    } 
@Override
public Object clone() throws CloneNotSupportedException{
       JArrayList result = null;
       result = (JArrayList) super.clone();
       result.aList = (ArrayList<Double>)aList.clone();
  //        result.aList = (ArrayList<Double>) this.aList.clone();
    return result;
}
@Override
public int hashCode(){
    int result = 0;
    result = aList.hashCode();
    return result;
}  
@Override
public String toString(){
   aList.toString();
    return aList.toString();
}
@Override
public Iterator<Double> iterator() {
        return new Iterator<Double>() {
            public int elem = 0;
            @Override
            public void remove() {
            }
            @Override
            public Double next() {
                return aList.get(elem++);
            }
            @Override
            public boolean hasNext() {
                if (elem < aList.size())
                    return true;
                else
                    return false;
            }
        };
    }

    @Override
    public void registerObserver(Observer o) {
          observer.add(o);
    }

    @Override
    public void removeObserver(Observer o) {
        int i = observer.indexOf(o);
        if (i>=0) 
            observer.remove(i);
    }

    @Override
    public void elementNotifyObservers(int index) {
        for ( int i =0; i< observer.size(); i++)
        {
           Observer observers = (Observer) observer.get(i); 
            observers.updateElement(index);
    }
 }
     
     public void updateNotifyObservers() {
        for ( int i =0; i< observer.size(); i++)
        {
           Observer observers = (Observer) observer.get(i); 
            observers.update();
    }
 }

}
